package com.mhz.cae.objects;

import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.input.touch.TouchEvent;

import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.mhz.cae.events.EventManager;
import com.mhz.cae.events.SelectItemEvent;
import com.mhz.cae.handlers.TrashableHandler;
import com.mhz.cae.util.CoordonateConverter;

public class Trampoline implements Item {

	// The object coordonates
	private final float mX;
	private final float mY;
	private final float mWidth;
	private final float mHeight;
	private final float mAngle;

	private boolean selected = false;

	private static final FixtureDef TRAMPOLINE_FIXURE_DEF = PhysicsFactory.createFixtureDef(0, 1.0f, 0.5f);

	// Sprite
	private Shape mFace;
	private Body mBody;

	private Trampoline(final float pX, final float pY, final float pWidth, final float pHeight, final float pAngle) {
		this.mX = pX;
		this.mY = pY;
		this.mWidth = pWidth;
		this.mHeight = pHeight;
		this.mAngle = pAngle;
	}

	public static Item createObject(final float pX, final float pY, final float pWidth, final float pHeight) {
		return new Trampoline(pX, pY, pWidth, pHeight, 0);
	}

	public static Item createObject(final float pX, final float pY, final float pWidth, final float pHeight, final float pAngle) {
		return new Trampoline(pX, pY, pWidth, pHeight, pAngle);
	}

	@Override
	public void initObject(final PhysicsWorld physicsWorld, final Scene scene) {
		final Item currentItem = this;
		// Create Face
		mFace = new Rectangle(mX, mY, mWidth, mHeight) {
			@Override
			public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
				switch (pSceneTouchEvent.getAction()) {
				case TouchEvent.ACTION_DOWN:
					if (!selected) {
						EventManager.getInstance().pushEvent(new SelectItemEvent(currentItem));
					}
					break;
				case TouchEvent.ACTION_MOVE:
					mBody.setTransform(CoordonateConverter.faceToBody(pSceneTouchEvent.getX(), 0) //
							, CoordonateConverter.faceToBody(pSceneTouchEvent.getY(), 0) //
							, mBody.getAngle());
					break;
				case TouchEvent.ACTION_UP:
					if (!selected) {
						EventManager.getInstance().pushEvent(new SelectItemEvent(currentItem));
					}
					break;
				}
				return true;
			}
		};
		mFace.setRotation(mAngle);
		// Attach Face to the scene
		scene.attachChild(mFace);
		scene.registerTouchArea(mFace);
		// Create Body
		mBody = PhysicsFactory.createBoxBody(physicsWorld, mFace, BodyType.StaticBody, TRAMPOLINE_FIXURE_DEF);
		physicsWorld.registerPhysicsConnector(new PhysicsConnector(mFace, mBody, true, true));

	}

	public void registerTrashable(final PhysicsWorld physicsWorld, final Scene scene, final Sprite trash) {
		scene.registerUpdateHandler(new TrashableHandler(physicsWorld, scene, trash, mFace));
	}

	@Override
	public void transform(final PhysicsWorld physicsWorld, final float pZoomFactor, float pAngle) {
		mFace.setScaleX(pZoomFactor);
		physicsWorld.destroyBody(mBody);
		mBody = PhysicsFactory.createBoxBody(physicsWorld, mFace, BodyType.StaticBody, TRAMPOLINE_FIXURE_DEF);
		physicsWorld.registerPhysicsConnector(new PhysicsConnector(mFace, mBody, true, true));
		mBody.setTransform(mBody.getPosition(), pAngle);
	}

	@Override
	public void setSelected(boolean pSelected) {
		selected = pSelected;
		if (selected) {
			mFace.setColor(0.1f, 0.2f, 0.3f);
		} else {
			mFace.setColor(1f, 1f, 1f);
		}
	}

	@Override
	public void resetObject() {
		// Nothing todo
	}
}
